import os
import subprocess
import venv
import shutil
from flask import Flask, render_template, request, jsonify, flash, redirect, url_for, send_from_directory, Response
import json
from werkzeug.utils import secure_filename
import threading
import sys
import psutil
import time
from collections import deque
from datetime import datetime, timedelta

app = Flask(__name__)
app.secret_key = os.urandom(24)

# 配置文件路径
SCRIPTS_CONFIG = 'scripts_config.json'
VENV_DIR = 'venvs'
UPLOAD_DIR = 'uploads'

# 输出限制配置
MAX_OUTPUT_LINES = 1000  # 每个脚本最多保存1000行输出
MAX_STORE_TIME = 3600  # 输出最多保存1小时
OUTPUT_CLEANUP_INTERVAL = 300  # 每5分钟清理一次

# 确保必要的目录存在
os.makedirs(VENV_DIR, exist_ok=True)
os.makedirs(UPLOAD_DIR, exist_ok=True)

# 存储运行中的进程
running_processes = {}
# 存储进程输出
process_outputs = {}
# 存储输出最后访问时间
output_last_access = {}

def cleanup_old_outputs():
    """清理旧的输出内容"""
    current_time = time.time()
    to_remove = []
    
    for name, last_access in output_last_access.items():
        # 如果脚本不在运行且超过保存时间，则清理
        if name not in running_processes and current_time - last_access > MAX_STORE_TIME:
            to_remove.append(name)
    
    for name in to_remove:
        if name in process_outputs:
            del process_outputs[name]
        del output_last_access[name]

def limit_output_lines(output_list):
    """限制输出行数"""
    if len(output_list) > MAX_OUTPUT_LINES:
        return list(output_list[-MAX_OUTPUT_LINES:])
    return output_list

# 启动定时清理任务
def start_cleanup_task():
    def cleanup_task():
        while True:
            time.sleep(OUTPUT_CLEANUP_INTERVAL)
            cleanup_old_outputs()
    
    cleanup_thread = threading.Thread(target=cleanup_task, daemon=True)
    cleanup_thread.start()

# 启动清理任务
start_cleanup_task()

def load_scripts():
    if os.path.exists(SCRIPTS_CONFIG):
        with open(SCRIPTS_CONFIG, 'r', encoding='utf-8') as f:
            return json.load(f)
    return {}

def save_scripts(scripts):
    with open(SCRIPTS_CONFIG, 'w', encoding='utf-8') as f:
        json.dump(scripts, f, ensure_ascii=False, indent=4)

def is_python_file(filename):
    """检查文件是否为Python文件"""
    return filename.lower().endswith('.py')

def save_uploaded_file(file, target_dir):
    """保存上传的文件到目标目录"""
    filename = secure_filename(file.filename)
    file_path = os.path.join(target_dir, filename)
    file.save(file_path)
    return file_path

def process_uploaded_files(files, script_name):
    """处理上传的文件（单个文件或文件夹）"""
    # 为这个脚本创建专门的目录
    script_dir = os.path.join(UPLOAD_DIR, secure_filename(script_name))
    if os.path.exists(script_dir):
        shutil.rmtree(script_dir)
    os.makedirs(script_dir)

    main_file = None
    file_list = []

    # 处理所有文件
    for file in files:
        if not file.filename:
            continue
        
        # 获取相对路径
        rel_path = file.filename.replace('\\', '/').lstrip('/')
        
        # 创建必要的子目录
        file_dir = os.path.join(script_dir, os.path.dirname(rel_path))
        os.makedirs(file_dir, exist_ok=True)
        
        # 保存文件
        file_path = os.path.join(script_dir, rel_path)
        file.save(file_path)
        file_list.append(rel_path)
        
        # 如果是Python文件，可能是主文件
        if is_python_file(file.filename):
            # 如果还没有主文件，或者这个文件名是main.py/[script_name].py
            if not main_file or any(file.filename.lower().endswith(x) for x in ['/main.py', f'/{script_name.lower()}.py']):
                main_file = rel_path

    if not main_file and file_list:
        # 如果没有找到主文件，使用第一个Python文件
        python_files = [f for f in file_list if is_python_file(f)]
        if python_files:
            main_file = python_files[0]

    if not main_file:
        raise ValueError("未找到任何Python文件")

    return {
        'dir': script_dir,
        'main_file': main_file,
        'files': file_list
    }

def get_venv_info(venv_name):
    """获取虚拟环境信息"""
    venv_path = os.path.join(VENV_DIR, venv_name)
    if not os.path.exists(venv_path):
        return None
    
    # 获取已安装的包列表
    python_path = os.path.join(venv_path, 'Scripts', 'python.exe')
    try:
        result = subprocess.run(
            [python_path, '-m', 'pip', 'list', '--format=json'],
            capture_output=True,
            text=True
        )
        packages = json.loads(result.stdout) if result.returncode == 0 else []
    except:
        packages = []
    
    # 获取Python版本
    try:
        result = subprocess.run(
            [python_path, '--version'],
            capture_output=True,
            text=True
        )
        python_version = result.stdout.strip() if result.returncode == 0 else '未知'
    except:
        python_version = '未知'
    
    return {
        'name': venv_name,
        'path': venv_path,
        'python_version': python_version,
        'packages': packages
    }

def build_file_tree(files, script):
    """构建文件树结构"""
    tree = []
    for file_path in files:
        parts = file_path.split('/')
        current = tree
        
        # 处理每一层目录
        for i, part in enumerate(parts):
            # 检查当前部分是否已存在
            existing = next((x for x in current if x['name'] == part), None)
            
            if i == len(parts) - 1:  # 文件
                current.append({
                    'name': part,
                    'path': file_path,
                    'type': 'file',
                    'is_python': part.lower().endswith('.py'),
                    'is_main': file_path == script['main_file']
                })
            else:  # 目录
                if not existing:
                    new_dir = {
                        'name': part,
                        'path': '/'.join(parts[:i+1]),
                        'type': 'directory',
                        'children': []
                    }
                    current.append(new_dir)
                    current = new_dir['children']
                else:
                    current = existing['children']
    
    return sorted(tree, key=lambda x: (x['type'] != 'directory', x['name']))

@app.route('/')
def home():
    """主页路由"""
    venvs = [d for d in os.listdir(VENV_DIR) if os.path.isdir(os.path.join(VENV_DIR, d))]
    return render_template('index.html', venvs=venvs)

@app.route('/scripts')
def manage_scripts():
    """脚本管理页面路由"""
    scripts = load_scripts()
    venvs = [d for d in os.listdir(VENV_DIR) if os.path.isdir(os.path.join(VENV_DIR, d))]
    
    # 获取搜索参数
    search_query = request.args.get('search', '').strip().lower()
    
    # 过滤脚本
    if search_query:
        filtered_scripts = {
            name: info for name, info in scripts.items()
            if search_query in name.lower() or
               search_query in info['main_file'].lower() or
               (info.get('venv', '') and search_query in info['venv'].lower())
        }
    else:
        filtered_scripts = scripts
    
    # 分页参数
    page = int(request.args.get('page', 1))
    per_page = 10  # 每页显示的脚本数量
    
    # 计算总页数
    total_scripts = len(filtered_scripts)
    total_pages = (total_scripts + per_page - 1) // per_page
    
    # 确保页码有效
    page = max(1, min(page, total_pages)) if total_pages > 0 else 1
    
    # 获取当前页的脚本
    script_items = list(filtered_scripts.items())
    start_idx = (page - 1) * per_page
    end_idx = start_idx + per_page
    current_page_scripts = dict(script_items[start_idx:end_idx])
    
    return render_template('scripts.html',
                         scripts=current_page_scripts,
                         venvs=venvs,
                         current_page=page,
                         total_pages=total_pages,
                         total_scripts=total_scripts,
                         search_query=search_query)

@app.route('/add_script', methods=['POST'])
def add_script():
    name = request.form.get('name')
    venv = request.form.get('venv')
    files = request.files.getlist('script_file')
    
    if not all([name, files]):
        flash('请填写所有必需字段并上传文件')
        return redirect(url_for('home'))
    
    try:
        # 处理上传的文件
        upload_info = process_uploaded_files(files, name)
        
        scripts = load_scripts()
        scripts[name] = {
            'path': os.path.join(upload_info['dir'], upload_info['main_file']),
            'dir': upload_info['dir'],
            'main_file': upload_info['main_file'],
            'files': upload_info['files'],
            'venv': venv
        }
        save_scripts(scripts)
        flash('脚本上传成功')
        
    except Exception as e:
        flash(f'上传失败: {str(e)}')
        if os.path.exists(os.path.join(UPLOAD_DIR, secure_filename(name))):
            shutil.rmtree(os.path.join(UPLOAD_DIR, secure_filename(name)))
    
    return redirect(url_for('home'))

@app.route('/download_script/<name>')
def download_script(name):
    scripts = load_scripts()
    if name not in scripts:
        flash('脚本不存在')
        return redirect(url_for('home'))
    
    script = scripts[name]
    if len(script['files']) > 1:
        # 如果是多个文件，创建zip文件
        zip_path = os.path.join(UPLOAD_DIR, f'{secure_filename(name)}.zip')
        shutil.make_archive(zip_path[:-4], 'zip', script['dir'])
        return send_from_directory(
            UPLOAD_DIR,
            f'{secure_filename(name)}.zip',
            as_attachment=True,
            download_name=f'{name}.zip'
        )
    else:
        # 单个文件直接下载
        return send_from_directory(
            os.path.dirname(script['path']),
            os.path.basename(script['path']),
            as_attachment=True,
            download_name=os.path.basename(script['path'])
        )

def create_venv(venv_path):
    """创建虚拟环境并确保配置文件存在"""
    builder = venv.EnvBuilder(with_pip=True)
    builder.create(venv_path)
    
    # 检查并确保pyvenv.cfg文件存在
    cfg_path = os.path.join(venv_path, 'pyvenv.cfg')
    if not os.path.exists(cfg_path):
        # 如果配置文件不存在，创建一个基本的配置
        with open(cfg_path, 'w', encoding='utf-8') as f:
            f.write(f"""home = {sys.prefix}
implementation = CPython
version_info = {'.'.join(map(str, sys.version_info[:3]))}
virtualenv = 20.24.5
include-system-site-packages = false
base-prefix = {sys.base_prefix}
base-exec-prefix = {sys.base_exec_prefix}
base-executable = {sys.executable}
""")

@app.route('/create-venv', methods=['POST'])
def create_venv_route():
    """创建虚拟环境"""
    venv_name = request.form.get('venv_name')
    python_path = request.form.get('python_path', 'python')  # 默认使用系统Python
    
    if not venv_name:
        flash('请提供虚拟环境名称')
        return redirect(url_for('manage_venvs'))
    
    venv_path = os.path.join(VENV_DIR, venv_name)
    if os.path.exists(venv_path):
        flash('虚拟环境已存在')
        return redirect(url_for('manage_venvs'))
    
    try:
        # 创建虚拟环境
        create_venv(venv_path)
        flash('虚拟环境创建成功')
    except Exception as e:
        flash(f'创建虚拟环境失败: {str(e)}')
    
    return redirect(url_for('manage_venvs'))

def get_python_path(script):
    """获取Python解释器路径，并确保虚拟环境可用"""
    if script.get('venv'):
        venv_path = os.path.join(VENV_DIR, script['venv'])
        python_path = os.path.join(venv_path, 'Scripts', 'python.exe')
        
        # 检查虚拟环境是否完整
        if not os.path.exists(python_path) or not os.path.exists(os.path.join(venv_path, 'pyvenv.cfg')):
            # 如果虚拟环境不完整，尝试重新创建
            try:
                shutil.rmtree(venv_path)
                create_venv(venv_path)
            except Exception as e:
                print(f"重新创建虚拟环境失败: {str(e)}")
                return sys.executable
        return python_path
    return sys.executable

@app.route('/run_script/<name>', methods=['POST'])
def run_script(name):
    print(f"\n开始处理运行脚本请求: {name}")
    scripts = load_scripts()
    if name not in scripts:
        print(f"脚本 {name} 不存在")
        return jsonify({'error': '脚本不存在'}), 404

    script = scripts[name]
    file_name = request.json.get('file', script['main_file'])
    if not file_name:
        print("未指定运行文件")
        return jsonify({'error': '未指定运行文件'}), 400

    script_path = os.path.join(script['dir'], file_name)
    print(f"脚本完整路径: {script_path}")
    if not os.path.exists(script_path):
        print(f"脚本文件不存在: {script_path}")
        return jsonify({'error': '脚本文件不存在'}), 404

    # 获取Python解释器路径
    python_path = get_python_path(script)
    print(f"使用的Python解释器: {python_path}")

    # 如果进程已经在运行，返回现有输出
    if name in running_processes:
        print(f"脚本 {name} 已在运行中")
        return jsonify({'error': '脚本已在运行'}), 400

    # 初始化输出存储
    process_outputs[name] = {'stdout': [], 'stderr': [], 'returncode': None}
    print(f"已初始化process_outputs[{name}]")
    print(f"当前所有运行的脚本: {list(process_outputs.keys())}")

    def process_output():
        print(f"开始运行脚本: {script_path}")
        
        # 创建 STARTUPINFO 对象
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = subprocess.SW_HIDE
        
        try:
            process = subprocess.Popen(
                [python_path, "-u", script_path],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True,
                bufsize=0,
                universal_newlines=True,
                startupinfo=startupinfo,
                env=dict(os.environ, PYTHONUNBUFFERED="1")
            )
            
            print(f"进程已启动，PID: {process.pid}")
            running_processes[name] = process
            output_last_access[name] = time.time()

            def read_output(pipe, type_):
                print(f"开始读取{type_}输出")
                try:
                    for line in iter(pipe.readline, ''):
                        if line:
                            line = line.strip()
                            print(f"收到{type_}输出: {line}")
                            if name in process_outputs:  # 确保键仍然存在
                                process_outputs[name][type_] = limit_output_lines(process_outputs[name][type_] + [line])
                            else:
                                print(f"警告：process_outputs中没有找到{name}")
                    print(f"{type_}输出读取结束")
                except Exception as e:
                    print(f"读取{type_}输出时发生错误: {str(e)}")

            # 创建两个线程分别读取stdout和stderr
            stdout_thread = threading.Thread(target=lambda: read_output(process.stdout, 'stdout'))
            stderr_thread = threading.Thread(target=lambda: read_output(process.stderr, 'stderr'))
            
            stdout_thread.start()
            stderr_thread.start()
            
            returncode = process.wait()
            print(f"进程已结束，返回码: {returncode}")
            if name in process_outputs:  # 确保键仍然存在
                process_outputs[name]['returncode'] = returncode
            
            stdout_thread.join()
            stderr_thread.join()
            
            # 确保读取所有剩余输出
            remaining_stdout, remaining_stderr = process.communicate()
            if remaining_stdout and name in process_outputs:
                print(f"剩余标准输出: {remaining_stdout}")
                new_lines = remaining_stdout.strip().split('\n')
                process_outputs[name]['stdout'] = limit_output_lines(process_outputs[name]['stdout'] + new_lines)
            if remaining_stderr and name in process_outputs:
                print(f"剩余错误输出: {remaining_stderr}")
                new_lines = remaining_stderr.strip().split('\n')
                process_outputs[name]['stderr'] = limit_output_lines(process_outputs[name]['stderr'] + new_lines)
            
            if name in running_processes:
                del running_processes[name]
                print(f"已清理进程信息")
                
        except Exception as e:
            print(f"运行脚本时发生错误: {str(e)}")
            if name in process_outputs:
                process_outputs[name]['stderr'].append(str(e))
            if name in running_processes:
                del running_processes[name]

    # 在后台启动进程
    thread = threading.Thread(target=process_output)
    thread.start()
    print(f"后台线程已启动")

    return jsonify({'message': '脚本已启动'})

@app.route('/script_status/<name>')
def script_status(name):
    """获取脚本运行状态和输出"""
    if name not in process_outputs:
        return jsonify({'error': '脚本未运行'}), 404

    # 更新最后访问时间
    output_last_access[name] = time.time()
    
    output = process_outputs[name]
    is_running = name in running_processes
    
    # 只保留最新的5条输出
    stdout_lines = output['stdout'][-5:] if output['stdout'] else []
    stderr_lines = output['stderr'][-5:] if output['stderr'] else []
    
    # 获取总行数
    total_stdout_lines = len(output['stdout'])
    total_stderr_lines = len(output['stderr'])
    
    response = {
        'is_running': is_running,
        'stdout': stdout_lines,
        'stderr': stderr_lines,
        'total_lines': {
            'stdout': total_stdout_lines,
            'stderr': total_stderr_lines
        },
        'returncode': output['returncode']
    }
    
    # 如果脚本已结束且获取了状态，等待一段时间后再清理输出
    if not is_running and output['returncode'] is not None:
        # 不立即删除，让客户端有机会获取最终状态
        if time.time() - output_last_access[name] > 60:  # 1分钟后清理
            del process_outputs[name]
            del output_last_access[name]
    
    return jsonify(response)

@app.route('/stop_script/<name>', methods=['POST'])
def stop_script(name):
    """终止运行中的脚本"""
    if name not in running_processes:
        return jsonify({'error': '脚本未在运行'}), 404
    
    try:
        process = running_processes[name]
        
        try:
            # 获取进程及其子进程
            parent = psutil.Process(process.pid)
            
            # 终止主进程
            process.terminate()
            
            try:
                # 等待进程结束
                process.wait(timeout=3)
            except subprocess.TimeoutExpired:
                # 如果等待超时，强制结束进程
                process.kill()
                
            # 清理进程信息
            del running_processes[name]
            
            return jsonify({'message': '脚本已停止'})
            
        except psutil.NoSuchProcess:
            # 如果进程已经不存在
            if name in running_processes:
                del running_processes[name]
            return jsonify({'message': '脚本已经停止'})
            
    except Exception as e:
        app.logger.error(f'停止脚本时出错: {str(e)}')
        # 确保清理进程信息
        if name in running_processes:
            del running_processes[name]
        return jsonify({'error': f'停止脚本失败: {str(e)}'}), 500

@app.route('/delete_script/<name>')
def delete_script(name):
    scripts = load_scripts()
    if name in scripts:
        # 删除整个脚本目录
        script_dir = scripts[name]['dir']
        try:
            if os.path.exists(script_dir):
                shutil.rmtree(script_dir)
            # 删除可能存在的zip文件
            zip_path = os.path.join(UPLOAD_DIR, f'{secure_filename(name)}.zip')
            if os.path.exists(zip_path):
                os.remove(zip_path)
        except Exception as e:
            flash(f'删除文件失败: {str(e)}')
        
        del scripts[name]
        save_scripts(scripts)
        flash('脚本删除成功')
    return redirect(url_for('home'))

@app.route('/manage_files/<name>')
def manage_files(name):
    scripts = load_scripts()
    if name not in scripts:
        flash('脚本不存在')
        return redirect(url_for('home'))
    
    script = scripts[name]
    # 构建文件树
    file_tree = build_file_tree(script['files'], script)
    
    return render_template('manage_files.html', script_name=name, file_tree=file_tree)

@app.route('/save_file/<script_name>/<path:file_path>', methods=['POST'])
def save_file(script_name, file_path):
    scripts = load_scripts()
    if script_name not in scripts:
        return jsonify({'error': '脚本不存在'}), 404
    
    script = scripts[script_name]
    full_path = os.path.join(script['dir'], file_path)
    
    try:
        content = request.json.get('content', '')
        with open(full_path, 'w', encoding='utf-8') as f:
            f.write(content)
        return jsonify({'message': '保存成功'})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/set_main_file/<script_name>/<path:file_path>')
def set_main_file(script_name, file_path):
    scripts = load_scripts()
    if script_name not in scripts:
        flash('脚本不存在')
        return redirect(url_for('manage_files', name=script_name))
    
    if not file_path.lower().endswith('.py'):
        flash('只能将Python文件设为主文件')
        return redirect(url_for('manage_files', name=script_name))
    
    script = scripts[script_name]
    if file_path not in script['files']:
        flash('文件不存在')
        return redirect(url_for('manage_files', name=script_name))
    
    script['main_file'] = file_path
    script['path'] = os.path.join(script['dir'], file_path)
    save_scripts(scripts)
    flash('已更新主文件')
    return redirect(url_for('manage_files', name=script_name))

@app.route('/venv')
def manage_venvs():
    """虚拟环境管理页面"""
    venvs = []
    for venv_name in os.listdir(VENV_DIR):
        venv_info = get_venv_info(venv_name)
        if venv_info:
            venvs.append(venv_info)
    return render_template('manage_venvs.html', venvs=venvs)

@app.route('/venv/delete/<name>')
def delete_venv(name):
    """删除虚拟环境"""
    venv_path = os.path.join(VENV_DIR, name)
    if not os.path.exists(venv_path):
        flash('虚拟环境不存在')
        return redirect(url_for('manage_venvs'))
    
    try:
        # 检查是否有脚本在使用这个虚拟环境
        scripts = load_scripts()
        using_scripts = [script_name for script_name, script in scripts.items() 
                        if script.get('venv') == name]
        
        if using_scripts:
            flash(f'无法删除：以下脚本正在使用此虚拟环境：{", ".join(using_scripts)}')
            return redirect(url_for('manage_venvs'))
        
        # 删除虚拟环境目录
        shutil.rmtree(venv_path)
        flash('虚拟环境删除成功')
    except Exception as e:
        flash(f'删除虚拟环境失败: {str(e)}')
    
    return redirect(url_for('manage_venvs'))

@app.route('/venv/install_package/<name>', methods=['POST'])
def install_package(name):
    """安装包到虚拟环境"""
    package = request.form.get('package')
    if not package:
        return jsonify({'error': '请提供包名称'}), 400
    
    venv_path = os.path.join(VENV_DIR, name)
    if not os.path.exists(venv_path):
        return jsonify({'error': '虚拟环境不存在'}), 404
    
    try:
        # 使用pip安装包
        python_path = os.path.join(venv_path, 'Scripts', 'python.exe')
        result = subprocess.run(
            [python_path, '-m', 'pip', 'install', package],
            capture_output=True,
            text=True
        )
        
        if result.returncode == 0:
            return jsonify({
                'message': f'成功安装 {package}',
                'output': result.stdout
            })
        else:
            return jsonify({
                'error': '安装失败',
                'output': result.stderr
            }), 500
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/venv/uninstall_package/<name>', methods=['POST'])
def uninstall_package(name):
    """从虚拟环境卸载包"""
    package = request.form.get('package')
    if not package:
        return jsonify({'error': '请提供包名称'}), 400
    
    venv_path = os.path.join(VENV_DIR, name)
    if not os.path.exists(venv_path):
        return jsonify({'error': '虚拟环境不存在'}), 404
    
    try:
        # 使用pip卸载包
        python_path = os.path.join(venv_path, 'Scripts', 'python.exe')
        result = subprocess.run(
            [python_path, '-m', 'pip', 'uninstall', '-y', package],
            capture_output=True,
            text=True
        )
        
        if result.returncode == 0:
            return jsonify({
                'message': f'成功卸载 {package}',
                'output': result.stdout
            })
        else:
            return jsonify({
                'error': '卸载失败',
                'output': result.stderr
            }), 500
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/change_venv/<name>', methods=['POST'])
def change_venv(name):
    """切换脚本的虚拟环境"""
    scripts = load_scripts()
    if name not in scripts:
        return jsonify({'error': '脚本不存在'}), 404
    
    data = request.json
    venv = data.get('venv', '')
    
    if venv:
        # 检查虚拟环境是否存在
        venv_path = os.path.join(VENV_DIR, venv)
        if not os.path.exists(venv_path):
            return jsonify({'error': '虚拟环境不存在'}), 404
    
    # 更新脚本的虚拟环境设置
    scripts[name]['venv'] = venv
    save_scripts(scripts)
    
    return jsonify({'message': '虚拟环境已更新'})

@app.route('/edit_file/<script_name>/<path:file_path>')
def edit_file(script_name, file_path):
    """获取文件内容用于编辑"""
    scripts = load_scripts()
    if script_name not in scripts:
        return jsonify({'error': '脚本不存在'}), 404
    
    script = scripts[script_name]
    if file_path not in script['files']:
        return jsonify({'error': '文件不存在'}), 404
    
    full_path = os.path.join(script['dir'], file_path)
    try:
        with open(full_path, 'r', encoding='utf-8') as f:
            content = f.read()
        return jsonify({'content': content})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/system_resources')
def get_system_resources():
    """获取系统资源信息"""
    cpu_percent = psutil.cpu_percent(interval=1)
    memory = psutil.virtual_memory()
    disk = psutil.disk_usage('/')
    
    # 获取正在运行的脚本数量
    running_scripts_count = len(running_processes)
    
    return jsonify({
        'cpu': {
            'percent': cpu_percent,
            'cores': psutil.cpu_count()
        },
        'memory': {
            'total': memory.total,
            'available': memory.available,
            'percent': memory.percent,
            'used': memory.used
        },
        'disk': {
            'total': disk.total,
            'used': disk.used,
            'free': disk.free,
            'percent': disk.percent
        },
        'running_scripts': running_scripts_count,
        'timestamp': time.time()
    })

if __name__ == '__main__':
    app.run(debug=True) 